package com.tegistuff.webos.run.debugger.breakpoints;

import com.intellij.javascript.debugger.breakpoints.JavaScriptBreakpointType;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.breakpoints.XBreakpointHandler;
import com.intellij.xdebugger.breakpoints.XBreakpointProperties;
import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
import com.tegistuff.webos.run.WebOSRunConfiguration;
import com.tegistuff.webos.run.debugger.WebOSDebuggerProxy;
import com.tegistuff.webos.util.WebOSFileMapper;
import org.jetbrains.annotations.NotNull;

import java.util.List;

/**
 * WebOSLineBreakpointHandler.java
 *
 * Copyright (C) 2011-2012 Timo Tegtmeier.
 * All rights reserved.
 */
public class WebOSLineBreakpointHandler extends XBreakpointHandler<XLineBreakpoint<XBreakpointProperties>> {

    private XDebugSession myDebugSession;
    private WebOSBreakpointMap myBreakpointMap;
    private WebOSRunConfiguration myRunConfiguration;
    private WebOSDebuggerProxy myDebuggerProxy;

    public WebOSLineBreakpointHandler(WebOSRunConfiguration runConfiguration,
                                      WebOSDebuggerProxy debuggerProxy, XDebugSession debugSession) {
        super(JavaScriptBreakpointType.class);
        myRunConfiguration = runConfiguration;
        myDebugSession = debugSession;
        myDebuggerProxy = debuggerProxy;
        myBreakpointMap = new WebOSBreakpointMap();
    }

    public void registerBreakpoint(@NotNull final XLineBreakpoint<XBreakpointProperties> xBreakpoint) {
        String file = WebOSFileMapper.MapPathToWebOS(myRunConfiguration, xBreakpoint.getFileUrl());
        if(file == null) {
            myDebugSession.reportError("Breakpoint could not be set: Unable to map path.");
            return;
        }
        WebOSBreakpointWrapper wrapper = myBreakpointMap.find(file, xBreakpoint.getLine());
        if(wrapper == null) {
            myDebuggerProxy.setLineBreakpoint(xBreakpoint, file, xBreakpoint.getLine());
        } else {
            myDebuggerProxy.setLineBreakpointState(wrapper, true);
        }
    }

    public void unregisterBreakpoint(@NotNull final XLineBreakpoint<XBreakpointProperties> xBreakpoint, final boolean temporary) {
        String file = WebOSFileMapper.MapPathToWebOS(myRunConfiguration, xBreakpoint.getFileUrl());
        if(file == null) {
            myDebugSession.reportError("Breakpoint could not be removed: Unable to map path.");
            return;
        }
        WebOSBreakpointWrapper wrapper = myBreakpointMap.find(xBreakpoint);
        if(wrapper == null) {
            myDebugSession.reportError("Breakpoint could not be removed: Breakpoint not previously set.");
            return;
        }

        if(temporary ) {
            myDebuggerProxy.setLineBreakpointState(wrapper, false);
        } else {
            myDebuggerProxy.removeLineBreakpoint(wrapper);
        }
    }
    
    public void addBreakpointToMap(WebOSBreakpointWrapper breakpointWrapper) {
        myBreakpointMap.add(breakpointWrapper);
    }

    public void removeBreakpointFromMap(WebOSBreakpointWrapper breakpointWrapper) {
        myBreakpointMap.remove(breakpointWrapper);
    }

    public void finalizeBreakpoints() {
        List<WebOSBreakpointWrapper> breakpoints = myBreakpointMap.getAllBreakpoints();
        for(WebOSBreakpointWrapper bp: breakpoints) {
            myDebuggerProxy.removeLineBreakpoint(bp);
        }
    }
    
    public WebOSBreakpointWrapper findBreakpointWrapper(String webOSPath, int lineNumber) {
        return myBreakpointMap.find(webOSPath, lineNumber);
    }
}
